package club.ruanx.movie.adapter.impl;

import club.ruanx.exception.BaseException;
import club.ruanx.movie.adapter.SpiderPersonAdapter;
import club.ruanx.movie.entity.Person;
import club.ruanx.movie.util.FileUploaderWithFeign;
import club.ruanx.spider.entity.DoubanPerson;
import club.ruanx.util.CollectionUtils;
import club.ruanx.util.StringUtils;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 阮胜
 * @date 2019/2/10 16:28
 */
@Component
@Slf4j
public class SpiderPersonAdapterImpl implements SpiderPersonAdapter {
    private static final String PERSON_API_URL = "https://api.douban.com/v2/movie/celebrity/%s?apikey=0b2bdeda43b5688921839c8ecb20399b";
    private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd");
    private static final Map<String, Integer> PERSON_ROLE_MAP;
    private final FileUploaderWithFeign fileUploaderWithFeign;

    static {
        PERSON_ROLE_MAP = new HashMap<>(3);
        PERSON_ROLE_MAP.put("普通", 0);
        PERSON_ROLE_MAP.put("演员", 1);
        PERSON_ROLE_MAP.put("导演", 2);
    }

    public SpiderPersonAdapterImpl(FileUploaderWithFeign fileUploaderWithFeign) {
        this.fileUploaderWithFeign = fileUploaderWithFeign;
    }

    @Override
    public Person adapter(String id) throws BaseException, IOException {
        String json = Jsoup.connect(String.format(PERSON_API_URL, id)).ignoreContentType(true).get().text();
        DoubanPerson doubanPerson = JSON.parseObject(json, DoubanPerson.class);
        Date birthday = parseBirthday(doubanPerson);
        String professions = parseProfession(doubanPerson);
        String image = parseImage(doubanPerson);
        String photos = parsePhotos(doubanPerson);
        String introduction = doubanPerson.getSummary();
        if (StringUtils.isEmpty(introduction)) {
            introduction = "该人物暂无简介";
        }
        return Person.builder()
                .name(doubanPerson.getName())
                .englishName(doubanPerson.getName_en())
                .gender(doubanPerson.getGender())
                .constellation(doubanPerson.getConstellation())
                .birthday(birthday)
                .professions(professions)
                .birthPlace(doubanPerson.getBorn_place())
                .introduction(introduction)
                .image(image)
                .photos(photos)
                .spiderId(doubanPerson.getId())
                .build();
    }

    private String parsePhotos(DoubanPerson doubanPerson) {
        List<DoubanPerson.PhotosBean> photos = doubanPerson.getPhotos();
        if (CollectionUtils.isEmpty(photos)) {
            return "";
        }
        List<String> images = photos.stream()
                .map(DoubanPerson.PhotosBean::getImage)
                .collect(Collectors.toList());
        return fileUploaderWithFeign.uploadImageFromUrl(images);
    }

    private String parseImage(DoubanPerson doubanPerson) {
        String small = doubanPerson.getAvatars().getSmall();
        if (StringUtils.isEmpty(small)) {
            return "";
        }
        String imgUrl = small.replace("s_ratio_celebrity", "l");
        return fileUploaderWithFeign.uploadImageFromUrl(imgUrl);
    }

    private String parseProfession(DoubanPerson doubanPerson) {
        List<DoubanPerson.WorksBean> works = doubanPerson.getWorks();
        if (CollectionUtils.isEmpty(works)) {
            return "[0,1]";
        }
        List<Integer> roleList = works.stream()
                .map(DoubanPerson.WorksBean::getRoles)
                .filter(roles -> !CollectionUtils.isEmpty(roles))
                .flatMap(Collection::stream)
                .map(PERSON_ROLE_MAP::get)
                .filter(role -> !StringUtils.isEmpty(role))
                .distinct()
                .sorted()
                .collect(Collectors.toList());
        return JSON.toJSONString(roleList);
    }

    private Date parseBirthday(DoubanPerson doubanPerson) {
        try {
            return SDF.parse(doubanPerson.getBirthday());
        } catch (ParseException e) {
            Calendar instance = Calendar.getInstance(Locale.CHINA);
            instance.set(1995, Calendar.JULY, 28);
            return instance.getTime();
        }
    }

}
